/*************************************************************************
    > File Name    : PageLib.cc
    > Author       : LiuLei
    > Mail         : 2261459486@qq.com 
    > Created Time : 2022年11月29日 星期二 14时49分35秒
 ************************************************************************/

#include "../../include/WebProcessor/PageLib.h"
#include <iostream>
#include <regex>
#include <fstream>
#include "../../lib/tinyxml2.h"
using std::cout;
using std::endl;
using std::ofstream;
using namespace tinyxml2;

PageLib::PageLib(Configuration *config, DirScanner &dirScanner)
: _dirScanner(dirScanner)
, _config(config)
{
    unordered_map<string, string> paths = _config->getConfigMap();
    string filepath = paths["xmldir"];
    _dirScanner(filepath);

    this->create();
}

PageLib::~PageLib()
{

}

void PageLib::create()
{
    vector<string> lib = _dirScanner.getFilePath();
    size_t id = 0;
    int pos = 0;

    // 遍历所有网页
    for(size_t idx = 0; idx != lib.size(); ++idx)
    {
        XMLDocument doc;
        doc.LoadFile(lib[idx].c_str());

        if(doc.ErrorID() != 0)
        {
            cout << "LoadFile error in PageLib::create()!" << endl;
        }
        
        XMLElement *itemNode = doc.FirstChildElement("rss")
            ->FirstChildElement("channel")
            ->FirstChildElement("item");

        while(itemNode)
        {
            string text;
            string title = itemNode->FirstChildElement("title")->GetText();
            string link = itemNode->FirstChildElement("link")->GetText();
            string content = itemNode->FirstChildElement("description")
                ? itemNode->FirstChildElement("description")->GetText()
                : itemNode->FirstChildElement("content")
                ? itemNode->FirstChildElement("content")->GetText()
                : "";

            std::regex destory1("<[^>]+>");
            content = regex_replace(content, destory1, "");
            std::regex destroy2("\n");
            content = regex_replace(content, destroy2, "");

            text = "<doc><docid>" + std::to_string(++id)
                + "</docid><url>" + link
                + "</url><title>" + title
                + "</title><content>" + content
                + "</content></doc>\n";
            int capacity = text.size();
            _offsetLib[id] = std::pair<int, int>(pos, capacity);
            pos += capacity;
            /* _pageLib.insert(_pageLib.end(), text); */
            _pageLib.emplace_back( text);
            itemNode = itemNode->NextSiblingElement("item");
        }
    }
}

void PageLib::storePageLib()
{
    cout << "Saving PageLib..." << endl;

    unordered_map<string, string> paths = _config->getConfigMap();
    string storePath = paths["webpage"];
    cout << storePath << endl;

    ofstream ofs;
    ofs.open(storePath, std::ios::out | std::ios::trunc);

    if(!ofs.good())
    {
        cout << "Open " << storePath << " error in PageLib::storePageLib()!" << endl;
        return ;
    }

    for(auto &elem : _pageLib)
    {
        ofs << elem;
    }

    ofs.close();
}

void PageLib::storeOffsetLib()
{
    cout << "Saving OffsetLib..." << endl;

    unordered_map<string, string> paths = _config->getConfigMap();
    string storePath = paths["newoffset"];
    cout << storePath << endl;

    ofstream ofs;
    ofs.open(storePath, std::ios::out | std::ios::trunc);

    if(!ofs.good())
    {
        cout << "Open " << storePath << " error in PageLib::storePageLib()!" << endl;
        return ;
    }

    for(size_t i = 1; i < _offsetLib.size(); ++i)
    {
        ofs << i << "  " << _offsetLib[i].first << " " << _offsetLib[i].second << endl;
    }

    ofs.close();
}

vector<string> PageLib::getPageLib()
{
    return _pageLib;
}

unordered_map<int, pair<int, int>> PageLib::getOffsetLib()
{
    return _offsetLib;
}
